package com.zbs.framework.common.utils.mp;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Getter;
import lombok.Setter;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * @author: Zbs
 * @createTime: 2020/12/18 14:54
 * 做一些非空判断，使业务代码块更加简洁
 */

@Getter
@Setter
public class MpQueryWrapper2<T> extends QueryWrapper<T> {
    private BaseMapper<T> baseMapper;


    public MpQueryWrapper2(){
    }

    public Page<T> page(Integer pageIndex, Integer pageSize,BaseMapper<T> baseMapper){
        Page<T> page = PageUtil.page(pageIndex, pageSize);
        return baseMapper.selectPage(page,this);
    }

    public List<T> list(BaseMapper<T> baseMapper){
        return baseMapper.selectList(this);
    }


    public T getOne(BaseMapper<T> baseMapper){
        return baseMapper.selectOne(this);
    }


    public Long count(BaseMapper<T> baseMapper){
        return baseMapper.selectCount(this);
    }


    @SafeVarargs
    public final MpQueryWrapper2<T> selectColumns(SFunction<T, ?>... columns){
        ArrayList<String> objects = new ArrayList<>();
        for (SFunction<T, ?> tsFunction : columns) {
            objects.add(ColumnMpUtil.getName(tsFunction));
        }
        super.select(objects.toArray(new String[]{}));
        return this;
    }

    public final MpQueryWrapper2<T> selectColumns(String... columns){
        super.select(columns);
        return this;
    }


    /**
     * 等于 =
     * @param column 字段
     * @param val 值
     * @return MpQueryWrapper
     */
    public MpQueryWrapper2<T> eq(SFunction<T, ?> column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.eq(ColumnMpUtil.getName(column),val);
        }
        return this;
    }

    public MpQueryWrapper2<T> eq(String column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.eq(column,val);
        }
        return this;
    }

    /**
     * 不等于 <>
     * @param column 字段
     * @param val 值
     * @return MpQueryWrapper
     */
    public MpQueryWrapper2<T> ne(SFunction<T, ?> column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.ne(ColumnMpUtil.getName(column),val);
        }
        return this;
    }

    public MpQueryWrapper2<T> ne(String column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.ne(column,val);
        }
        return this;
    }

    /**
     * 大于 >
     * @param column 字段
     * @param val 值
     * @return MpQueryWrapper
     */
    public MpQueryWrapper2<T> gt(SFunction<T, ?> column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.gt(ColumnMpUtil.getName(column),val);
        }
        return this;
    }

    public MpQueryWrapper2<T> gt(String column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.gt(column,val);
        }
        return this;
    }

    /**
     * 大于等于 >=
     * @param column 字段
     * @param val 值
     * @return MpQueryWrapper
     */
    public MpQueryWrapper2<T> ge(SFunction<T, ?> column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.ge(ColumnMpUtil.getName(column),val);
        }
        return this;
    }

    public MpQueryWrapper2<T> ge(String column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.ge(column,val);
        }
        return this;
    }

    /**
     * 小于 <
     * @param column 字段
     * @param val 值
     * @return MpQueryWrapper
     */
    public MpQueryWrapper2<T> lt(SFunction<T, ?> column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.lt(ColumnMpUtil.getName(column),val);
        }
        return this;
    }

    public MpQueryWrapper2<T> lt(String column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.lt(column,val);
        }
        return this;
    }

    /**
     * 小于等于 <=
     * @param column 字段
     * @param val 值
     * @return MpQueryWrapper
     */
    public MpQueryWrapper2<T> le(SFunction<T, ?> column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.le(ColumnMpUtil.getName(column),val);
        }
        return this;
    }

    public MpQueryWrapper2<T> le(String column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.le(column,val);
        }
        return this;
    }

    public MpQueryWrapper2<T> like(SFunction<T, ?> column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.like(ColumnMpUtil.getName(column),val);
        }
        return this;
    }

    public MpQueryWrapper2<T> like(String column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.like(column,val);
        }
        return this;
    }

    public MpQueryWrapper2<T> notLike(SFunction<T, ?> column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.notLike(ColumnMpUtil.getName(column),val);
        }
        return this;
    }

    public MpQueryWrapper2<T> notLike(String column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.notLike(column,val);
        }
        return this;
    }

    /**
     * LIKE '%值'
     * @param column 字段
     * @param val 值
     * @return MpQueryWrapper
     */
    public MpQueryWrapper2<T> likeLeft(SFunction<T, ?> column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.likeLeft(ColumnMpUtil.getName(column),val);
        }
        return this;
    }

    public MpQueryWrapper2<T> likeLeft(String column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.likeLeft(column,val);
        }
        return this;
    }

    /**
     * LIKE '值%'
     * @param column 字段
     * @param val 值
     * @return MpQueryWrapper
     */
    public MpQueryWrapper2<T> likeRight(SFunction<T, ?> column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.likeRight(ColumnMpUtil.getName(column),val);
        }
        return this;
    }

    public MpQueryWrapper2<T> likeRight(String column, Object val){
        if (!ObjectUtils.isEmpty(val)){
            super.likeRight(column,val);
        }
        return this;
    }

    public MpQueryWrapper2<T> between(SFunction<T, ?> column, Object val1, Object val2){
        super.between(ColumnMpUtil.getName(column),val1,val2);
        return this;
    }

    public MpQueryWrapper2<T> between(String column, Object val1, Object val2){
        super.between(column,val1,val2);
        return this;
    }

    public MpQueryWrapper2<T> or(Consumer<QueryWrapper<T>> consumer){
        super.or(consumer);
        return this;
    }

    public MpQueryWrapper2<T> and(Consumer<QueryWrapper<T>> consumer){
        super.and(consumer);
        return this;
    }

    public MpQueryWrapper2<T> notBetween(SFunction<T, ?> column, Object val1, Object val2){
        super.notBetween(ColumnMpUtil.getName(column),val1,val2);
        return this;
    }

    public MpQueryWrapper2<T> notBetween(String column, Object val1, Object val2){
        super.notBetween(column,val1,val2);
        return this;
    }

    public MpQueryWrapper2<T> isNull(SFunction<T, ?> column){
        super.isNull(ColumnMpUtil.getName(column));
        return this;
    }

    public MpQueryWrapper2<T> isNull(String column){
        super.isNull(column);
        return this;
    }
    public MpQueryWrapper2<T> isNotNull(SFunction<T, ?> column){
        super.isNotNull(ColumnMpUtil.getName(column));
        return this;
    }

    public MpQueryWrapper2<T> isNotNull(String column){
        super.isNotNull(column);
        return this;
    }

    public MpQueryWrapper2<T> in(SFunction<T, ?> column, Object... values) {
        List<Object> collect = Arrays.stream(values).filter(param -> !ObjectUtils.isEmpty(param)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(collect)) {
            super.in(ColumnMpUtil.getName(column), values);
        }
        return this;
    }

    public MpQueryWrapper2<T> in(String column, Object... values) {
        List<Object> collect = Arrays.stream(values).filter(param -> !ObjectUtils.isEmpty(param)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(collect)) {
            super.in(column, values);
        }
        return this;
    }


    public MpQueryWrapper2<T> in(SFunction<T, ?> column, Collection<?> coll){
        if (!CollectionUtils.isEmpty(coll)){
            super.in(ColumnMpUtil.getName(column),coll);
        }
        return this;
    }

    public MpQueryWrapper2<T> in(String column, Collection<?> coll){
        if (!CollectionUtils.isEmpty(coll)){
            super.in(column,coll);
        }
        return this;
    }

    public MpQueryWrapper2<T> notIn(SFunction<T, ?> column, Object... values){
        List<Object> collect = Arrays.stream(values).filter(param -> !ObjectUtils.isEmpty(param)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(collect)) {
            super.notIn(ColumnMpUtil.getName(column), values);
        }
        return this;
    }

    public MpQueryWrapper2<T> notIn(String column, Object... values){
        List<Object> collect = Arrays.stream(values).filter(param -> !ObjectUtils.isEmpty(param)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(collect)) {
            super.notIn(column, values);
        }
        return this;
    }

    public MpQueryWrapper2<T> notIn(SFunction<T, ?> column, Collection<?> coll){
        if (!CollectionUtils.isEmpty(coll)){
            super.notIn(ColumnMpUtil.getName(column),coll);
        }
        return this;
    }

    public MpQueryWrapper2<T> notIn(String column, Collection<?> coll){
        if (!CollectionUtils.isEmpty(coll)){
            super.notIn(column,coll);
        }
        return this;
    }

    @SafeVarargs
    public final MpQueryWrapper2<T> groupByColumn(SFunction<T, ?>... column){
        ArrayList<String> objects = new ArrayList<>();
        for (SFunction<T, ?> tsFunction : column) {
            objects.add(ColumnMpUtil.getName(tsFunction));
        }
        super.groupBy(objects);
        return this;
    }

    public final MpQueryWrapper2<T> groupByColumn(String... column){
        if (column != null && column.length > 0) {
            super.groupBy(Arrays.asList(column));
        }
        return this;
    }

    @SafeVarargs
    public final MpQueryWrapper2<T> orderByAscColumn(SFunction<T, ?>... column){
        ArrayList<String> objects = new ArrayList<>();
        for (SFunction<T, ?> tsFunction : column) {
            objects.add(ColumnMpUtil.getName(tsFunction));
        }
        super.orderByAsc(objects);
        return this;
    }

    public final MpQueryWrapper2<T> orderByAscColumn(String... column){
        if (column != null && column.length > 0) {
            super.orderByAsc(Arrays.asList(column));
        }
        return this;
    }


    @SafeVarargs
    public final MpQueryWrapper2<T> orderByDescColumn(SFunction<T, ?>... column){
        ArrayList<String> objects = new ArrayList<>();
        for (SFunction<T, ?> tsFunction : column) {
            objects.add(ColumnMpUtil.getName(tsFunction));
        }
        super.orderByDesc(objects);
        return this;
    }

    public final MpQueryWrapper2<T> orderByDescColumn(String... column){
        if (column != null && column.length > 0) {
            super.orderByDesc(Arrays.asList(column));
        }
        return this;
    }


    public MpQueryWrapper2<T> having(String sqlHaving, Object... params){
        List<Object> collect = Arrays.stream(params).filter(param -> !ObjectUtils.isEmpty(param)).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(collect)) {
            super.having(sqlHaving,params);
        }
        return this;
    }

    public MpQueryWrapper2<T> func(Consumer<QueryWrapper<T>> consumer){
        super.func(consumer);
        return this;
    }
}
